package com.openharmony.filepicker.config;

import com.openharmony.filepicker.ResourceTable;
import com.openharmony.filepicker.engine.ImageEngine;
import com.openharmony.filepicker.filetype.FileType;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.global.resource.NotExistException;
import ohos.global.resource.ResourceManager;
import ohos.global.resource.WrongTypeException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class FilePickerConfig {

    /**
     * 手机内部的外置存储，也就是内置 SD 卡
     */
    public static final String STORAGE_EXTERNAL_STORAGE = "STORAGE_EXTERNAL_STORAGE";
    public static final String STORAGE_CUSTOM_ROOT_PATH = "STORAGE_CUSTOM_ROOT_PATH";

    private FilePickerManager pickerManager;
    private ArrayList<FileType> customFileTypes = new ArrayList<>(2);
    private ResourceManager contextRes;

    private boolean isAutoFilter = false;
    /**
     * 是否显示隐藏文件，默认隐藏
     * 以符号 . 开头的文件或文件夹视为隐藏
     */
    private boolean isShowHiddenFiles = false;

    /**
     * 是否显示选中框，默认显示
     */
    private boolean isShowingCheckBox = true;

    /**
     * 在选中时是否忽略文件夹
     */
    private boolean isSkipDir = true;

    /**
     * 是否是单选
     * 如果是单选，则隐藏顶部【全选/取消全选按钮】
     */
    private boolean singleChoice = false;

    /**
     * 最大可被选中数量
     */
    private int maxSelectable = Integer.MAX_VALUE;

    /**
     * 存储类型
     */
    private String mediaStorageName = "";

    /**
     * 自定义存储类型，根据此返回根目录
     */
    private String mediaStorageType = STORAGE_EXTERNAL_STORAGE;

    /**
     * 自定义根目录路径，需要先设置 [mediaStorageType] 为 [STORAGE_CUSTOM_ROOT_PATH]
     */
    private String customRootPath = "";

    /**
     * 自定义过滤器
     */
    private AbstractFileFilter selfFilter = null;

    /**
     * 自定文件类型甄别器和默认类型甄别器
     */
    private AbstractFileDetector customDetector = null;

    private DefaultFileDetector defaultFileDetector;

    /**
     * 点击操作接口，采用默认实现
     */
    private FileItemOnClickListener fileItemOnClickListener = null;

    //TODO 通过资源文件获取主题设置
    /**
     * 主题
     */
    public int themeId;

    /**
     * 全选文字，取消全选文字，返回文字，已选择文字，确认按钮，选择限制提示语，空列表提示
     */
    private String selectAllText;
    private String deSelectAllText;
    private int hadSelectedText;
    private String confirmText;
    private int maxSelectCountTips;
    private String emptyListTips;

    private ImageEngine customImageEngine;


    public FilePickerConfig(FilePickerManager pickerManager) {
        this.pickerManager = pickerManager;
        contextRes = pickerManager.getContextRef().get().getResourceManager();
        try {
            mediaStorageName = contextRes
                    .getElement(ResourceTable.String_file_picker_tv_sd_card)
                    .getString();
            selectAllText = contextRes
                    .getElement(ResourceTable.String_file_picker_tv_select_all)
                    .getString();
            deSelectAllText = contextRes
                    .getElement(ResourceTable.String_file_picker_tv_deselect_all)
                    .getString();
            hadSelectedText = ResourceTable.String_file_picker_selected_count;
            confirmText = contextRes
                    .getElement(ResourceTable.String_file_picker_tv_select_done)
                    .getString();
            maxSelectCountTips = ResourceTable.String_max_select_count_tips;
            emptyListTips = contextRes
                    .getElement(ResourceTable.String_empty_list_tips_file_picker)
                    .getString();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        } catch (WrongTypeException e) {
            e.printStackTrace();
        }

        defaultFileDetector = new DefaultFileDetector();
        defaultFileDetector.registerDefaultTypes();
    }

    public FilePickerConfig showHiddenFiles(boolean isShow) {
        isShowHiddenFiles = isShow;
        return this;
    }

    public FilePickerConfig showCheckBox(boolean isShow) {
        isShowHiddenFiles = isShow;
        return this;
    }

    public FilePickerConfig skipDirWhenSelect(boolean isSkip) {
        isSkipDir = isSkip;
        return this;
    }

    public FilePickerConfig maxSelectable(int max) {
        maxSelectable = max < 0 ? Integer.MAX_VALUE : max;
        return this;
    }

    public FilePickerConfig storageType(String volumeName, String storageMediaType) {
        this.mediaStorageName = volumeName;
        this.mediaStorageType = storageMediaType;
        return this;
    }

    public FilePickerConfig setCustomRootPath(String path) {
        this.customRootPath = path;
        return this;
    }

    public FilePickerConfig filter(AbstractFileFilter fileFilter) {
        this.selfFilter = fileFilter;
        return this;
    }

    public FilePickerConfig setItemClickListener(FileItemOnClickListener fileItemOnClickListener) {
        this.fileItemOnClickListener = fileItemOnClickListener;
        return this;
    }

    public FilePickerConfig setTheme(int themeId) {
        this.themeId = themeId;
        return this;
    }

    public FilePickerConfig enableSingleChoice() {
        this.singleChoice = true;
        return this;
    }

    /**
     * 设置界面的字符串，包括：
     * 选中全部[selectAllString]
     * 取消选中[unSelectAllString]
     * 已选择[hadSelectedStrRes]
     * 确认[confirmText]
     * 多选限制提示：“您只能选择 1 个条目”[maxSelectCountTipsStrRes]
     * 空试图体视：“空空如也”[emptyListTips]
     * 注意：
     * [hadSelectedStrRes] 和 [maxSelectCountTipsStrRes] 是 String format 限制的字符串，
     * 你需要传入 [R.string.file_picker_selected_count] 类似的
     * 中的 id，并且包含一个可传入 Int 类型参数的占位符
     *----------------------------------------------------------------------------------------------
     * Set the string of the interface, including:
      * Select all [selectAllString]
      * Uncheck [unSelectAllString]
      * Selected [hadSelectedStrRes]
      * Confirm [confirmText]
      * Multiple selection limit prompt: "You can only select 1 item" [maxSelectCountTipsStrRes]
      * Empty tries to look at the stereo: "empty as well" [emptyListTips]
     * Note:
     * [hadSelectedStrRes] and [maxSelectCountTipsStrRes]
     * are strings of String format restrictions,
     * you need to pass some string like [R.string.file_picker_selected_count]
     * The id in * and contains a placeholder for passing in an Int type parameter
     */
    public FilePickerConfig setText(
            String selectAllString,
            String unSelectAllString,
            int hadSelectedStrRes,
            String confirmText,
            int maxSelectCountTipsStrRes,
            String emptyListTips
    ) {
        this.selectAllText = selectAllString;
        this.deSelectAllText = unSelectAllString;
        this.hadSelectedText = hadSelectedStrRes;
        this.confirmText = confirmText;
        this.maxSelectCountTips = maxSelectCountTipsStrRes;
        this.emptyListTips = emptyListTips;
        return this;
    }

    public FilePickerConfig imageEngine(ImageEngine ie) {
        this.customImageEngine = ie;
        return this;
    }

    /**
     * @author rosuh@qq.com
     * @date 2020/9/15
     * 用于注册你自定义的文件类型。
     * 库将自动调用你的自定义类型里的[FileType.verify]来识别文件。
     * 如果识别成功，就会自动填充到 [me.rosuh.filepicker.bean.FileItemBeanImpl.fileType] 中
     * 如果[autoFilter]为 true，那么库将自动过滤掉不符合你自定义类型的文件。不会在结果中显示出来。
     * 如果为 false，那么就只是检测类型。不会对结果列表做修改
     * 你不需要再调用[fileType]方法，否则将默认使用[fileType]
     * ---
     * Pass your custom [FileType] instances list and all done! This lib would auto detect file type
     * by using [FileType.verify].
     * If [autoFilter] is true, this lib will filter result by using your custom file types.
     * If [autoFilter] is true,
     * the library will automatically filter out files that do not meet your custom type.
     * Will not show up in the results.
     * * If it is false, then only the detection type. No changes to the result list
     * You don't need to call [fileType] again !
     */
    public FilePickerConfig registerFileType(List<FileType> types, boolean autoFilter) {
        this.customFileTypes.addAll(types);
        this.defaultFileDetector.registerCustomTypes(customFileTypes);
        this.isAutoFilter = autoFilter;
        return this;
    }

    public FilePickerConfig registerFileType(List<FileType> types) {
        this.customFileTypes.addAll(types);
        this.defaultFileDetector.registerCustomTypes(customFileTypes);
        this.isAutoFilter = true;
        return this;
    }

    public void forResult(int requestCode) {
        Ability ability = pickerManager.getContextRef().get();
        AbilitySlice abilitySlice = pickerManager.getFragmentRef().get();

        String actualBundleName = ability.getElementName().getBundleName();

        Intent intent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withDeviceId("")
                .withBundleName(actualBundleName)
                .withAbilityName("com.openharmony.filepicker.FilePickerAbility")
                .build();
        intent.setOperation(operation);

        if (abilitySlice == null) {
            ability.startAbilityForResult(intent, requestCode);
        } else {
            abilitySlice.startAbilityForResult(intent, requestCode);
        }
    }

    public void clear() {
        this.customFileTypes.clear();
        this.customImageEngine = null;
        this.fileItemOnClickListener = null;
        this.selfFilter = null;
        this.customDetector = null;
        this.defaultFileDetector.clear();
    }

    public boolean isAutoFilter() {
        return isAutoFilter;
    }

    public void setAutoFilter(boolean autoFilter) {
        isAutoFilter = autoFilter;
    }

    public boolean isShowHiddenFiles() {
        return isShowHiddenFiles;
    }

    public boolean isShowingCheckBox() {
        return isShowingCheckBox;
    }

    public boolean isSkipDir() {
        return isSkipDir;
    }

    public boolean isSingleChoice() {
        return singleChoice;
    }

    public int getMaxSelectable() {
        return maxSelectable;
    }

    public String getMediaStorageName() {
        return mediaStorageName;
    }

    public String getMediaStorageType() {
        return mediaStorageType;
    }

    public String getCustomRootPath() {
        return customRootPath;
    }

    public AbstractFileFilter getSelfFilter() {
        return selfFilter;
    }

    public DefaultFileDetector getDefaultFileDetector() {
        return defaultFileDetector;
    }

    public FileItemOnClickListener getFileItemOnClickListener() {
        return fileItemOnClickListener;
    }

    public int getThemed() {
        return themeId;
    }

    public String getSelectAllText() {
        return selectAllText;
    }

    public String getDeSelectAllText() {
        return deSelectAllText;
    }

    public int getHadSelectedText() {
        return hadSelectedText;
    }

    public String getConfirmText() {
        return confirmText;
    }

    public int getMaxSelectCountTips() {
        return maxSelectCountTips;
    }

    public String getEmptyListTips() {
        return emptyListTips;
    }

    public ImageEngine getCustomImageEngine() {
        return customImageEngine;
    }
}
